"""Utilities for dealing with HTTP"""

import re

import django.http
from django.shortcuts import render_to_response 
import django.utils.encoding


class MethodOverrideMiddleware(object):
    """Allows clients to override the HTTP method of the request.
    
    This middleware supports overriding of the effective HTTP method via the
    ``X-HTTP-Method-Override`` header or POST parameter.
    
    >>> ware = MethodOverrideMiddleware()
    >>> request = django.http.HttpRequest()
    >>> request.method = 'GET'
    >>> request.META['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT'
    >>> ware.process_request(request)
    >>> request.method
    'GET'

    >>> request.method = 'POST'
    >>> ware.process_request(request)
    >>> request.method
    'PUT'

    >>> request.method = 'POST'
    >>> del request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
    >>> request.POST['X-HTTP-Method-Override'] = 'DELETE'
    >>> ware.process_request(request)
    >>> request.method
    'DELETE'

    >>> request.method = 'POST'
    >>> request.POST['X-HTTP-Method-Override'] = 'UNKNOWN'
    >>> response = ware.process_request(request)
    >>> response.status_code
    400
    """
    
    def process_request(self, request):
        if (request.method == 'POST') and \
           not re.match(r'/mock/[0-9A-Za-z_-]+', request.path):
            override = None
            if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
                override = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
            elif 'X-HTTP-Method-Override' in request.POST:
                override = request.POST['X-HTTP-Method-Override']
            
            if override is None:
                return
            elif override.upper() == 'PUT':
                request.method = 'PUT'
                request.META['REQUEST_METHOD'] = 'PUT'
                request.PUT = request.POST
            elif override.upper() == 'DELETE':
                request.method = 'DELETE'
                request.META['REQUEST_METHOD'] = 'DELETE'
                request.DELETE = request.POST
            else:
                return django.http.HttpResponseBadRequest()


class HttpResponseSeeOther(django.http.HttpResponse):
    status_code = 303

    def __init__(self, redirect_to):
        django.http.HttpResponse.__init__(self)
        self['Location'] = django.utils.encoding.iri_to_uri(redirect_to)

class HttpResponseNotImplemented(django.http.HttpResponse):
    status_code = 501


def error_to_response(status, *args, **kwargs):
    """Render a template to an `HttpResponse` object with error `status`."""
    response = render_to_response(*args, **kwargs)
    response.status_code = status
    return response
